﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TestSign
{
    public  class JsonUtil
    {
            /**
        * 生成特征字符串
        * 
        * @param jsonObject
        * @return
        * @throws Exception
        */
        public static String gen(JObject jsonObject, String salt)
        {

            StringBuilder builder = new StringBuilder();
            IDictionary<String, IList<String>> kvs = new Dictionary<String, IList<String>>();
            List<String> keys = new List<String>();
            fetchLeafKV(jsonObject, kvs);

            keys.AddRange(kvs.Keys);
            keys.Remove("sign");
            keys.Sort();

            foreach (var key in keys)
            {
                String value = mergeValues((List<String>)kvs[key]);
                if (!string.IsNullOrEmpty(value))
                    builder.AppendFormat("{0}={1}&", key, value);
            }

            builder.Remove(builder.Length - 1, 1);
            return builder.ToString() + salt;
        }

        private static String mergeValues(List<String> vls)
        {
            String result = null;
            StringBuilder sbVls = new StringBuilder();
            if (vls != null && vls.Count > 0)
            {
                vls.Sort();
                //Collections.sort(vls);
                foreach (var obj in vls)
                {
                    sbVls.AppendFormat("{0}-", obj);
                }


                if (sbVls.Length > 0)
                    sbVls.Remove(sbVls.Length - 1, 1);
                result = sbVls.ToString();
            }
            return result;
        }



        private static void fetchLeafKV(JObject jsonObject, IDictionary<String, IList<String>> kvs)
        {
            foreach (var item in jsonObject)
            {
                doFetchLeafKV(item.Key, item.Value, kvs);
            }

        }


        private static void doFetchLeafKV(String key, Object valObj, IDictionary<String, IList<String>> kvs)
        {
            if (valObj == null)
            {
                return;
            }

            if ((valObj is JObject))
            {
                fetchLeafKV((JObject)valObj, kvs);
            }
            else if ((valObj is JArray))
            {

                JArray array = (JArray)valObj;
                for (int i = 0; i < array.Count(); i++)
                {
                    doFetchLeafKV(key, array[i], kvs);
                }
            }
            else
            {
                IList<String> vLst = null;
                String lKey = key;
                if (kvs.ContainsKey(lKey))
                {
                    vLst = kvs[lKey];
                }
                else
                {
                    vLst = new List<String>();
                    kvs.Add(lKey, vLst);
                }
                vLst.Add(valObj.ToString());
            }
        }
    }
}
